/***************************************************************************
 *   KShootout - online shootout card game.                                *
 *   Copyright (C) 2008, 2009  MacJariel                                   *
 *                                                                         *
 *   KShootout is free software: you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   KShootout is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with KShootout.  If not, see <http://www.gnu.org/licenses/>.    *
 ***************************************************************************/
#ifndef __SERVERCONNECTION_H__
#define __SERVERCONNECTION_H__

#include "gametypes.h"

#include <QObject>
#include <QString>
#include <QList>

class QTcpSocket;

class Parser;
class ServerInfoData;


namespace client
{

    class Application;

    /**
     * The ServerConnection class manages connection with server.
     * @author MacJariel
     */
    class ServerConnection: public QObject
    {
        Q_OBJECT;
        friend class Application;
    public:

        /// Returns pointer to server connection.
        static ServerConnection* instance() {
            return smp_instance;
        }

        /// Returns whether client is connected to a server.
        inline bool isConnected() const {
            return mp_parser != 0;
        }

        /// Returns the name of the server to which the client is connected.
        QString serverName() const;

        /// Returns the hostname of the server to which the client is connected.
        inline QString hostName() const {
            return m_serverHost;
        }

        /// Connects to the server.
        void connectToServer(const QString& serverHost, int serverPort);

        /// Disconnects from the server.
        void disconnectFromServer();

        void sendQueryGet(const QueryGetPtr&, QueryResultHandler*);

        void sendAction(const ActionDataPtr&);


    signals:
        /**
         * This signal is emitted after a game event is received. The gameEvent
         * parameter describes the received game event.
         */
        void gameEventReceived(const GameEventDataPtr& gameEvent);

        /**
         * This signal is emitted after a server event is received. The serverEvent
         * parameter describes the received server event.
         */
        void serverEventReceived(const ServerEventDataPtr& serverEvent);

        /**
         * This signal is emitted after client receives data from server.
         * It can be used for debugging purposes.
         */
        void incomingData(const QByteArray&);

        /**
         * This signal is emitted after client sends data to server.
         * It can be used for debugging purposes.
         */
        void outgoingData(const QByteArray&);

    private slots:
        // callbacks from parser:
        void onStreamOpened();
        void onStreamClosed();
        void onParserError();

        // callbacks from socket
        void onSocketStateChanged();
        void onSocketError();

    private:
        ServerConnection();
        virtual ~ServerConnection();

        class QueryHandler;
        friend class QueryHandler;

        QueryHandler*       mp_handler;
        QTcpSocket*         mp_tcpSocket;
        Parser*             mp_parser;
        QString             m_serverHost;
        ServerInfoData*     mp_serverInfo;

        static ServerConnection* smp_instance;
    };
}
#endif
